package org.springblade.auth.endpoint;

import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.shy.core.sso.client.util.SsoUtil;
import org.shy.core.sso.common.entity.SsoUserInfo;
import org.springblade.auth.utils.TokenUtil;
import org.springblade.core.jwt.JwtUtil;
import org.springblade.core.jwt.props.JwtProperties;
import org.springblade.core.launch.constant.TokenConstant;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.WebUtil;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.entity.UserInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * description: token生成类 <br>
 * date: 2022/3/19 10:43 <br>
 * author: yzpang <br>
 * version: 1.0 <br>
 */
@NonDS
@ApiSort(1)
@RestController
@AllArgsConstructor
@Api(value = "用户授权认证", tags = "授权接口")
@Slf4j
@RequestMapping("token")
public class BladeSsoEndPoint {
	private final JwtProperties jwtProperties;
	/**
	 * ##目前弃用##
	 * description: 用户登录，跳转到认证服务 <br>
	 * author: yzpang <br>
	 * param:
	 **/
	@Deprecated
	@GetMapping("/oauth/login")
	public Kv login(){
		String requestUrl = WebUtil.getRequest().getRequestURL().toString();
		Kv kv = Kv.create();
		/*kv.put("apiUrl", bladeSsoProperties.getLoginUrl());
		kv.put("returnUrl", "http://192.168.4.171:8100/oauth/ssoVerify");*/
		return kv;
	}



	/**
	 * description: 客户端验证临时票据，从认证服务获取用户信息的token <br>
	 * author: yzpang <br>
	 * param:
	 * @return
	 **/
	@PostMapping("/oauth/ssoVerify")
	public R<Kv> tmpTicket(){
		String tmpTicket = WebUtil.getRequest().getParameter("tmpTicket");
		log.info("接收临时票据:" + tmpTicket);
		SsoUserInfo ssoUserInfo  = SsoUtil.fetchUserInfo(tmpTicket);
		if (null == ssoUserInfo){
			log.error("获取用户信息为空");
			return R.fail("获取用户信息为空");
		}
		return R.data(createBladeToken(ssoUserInfo));
	}

	public Map createToken(SsoUserInfo ssoUserInfo){
		// TODO 子应用使用用户信息自定义生成token
		return null;
	}

	/**
	 * description: 根据sso服务器返回的用户信息生成token 不同token生成策略在此方法实现 <br>
	 * date: 2022/3/22 11:09 <br>
	 * author: yzpang <br>
	 * param: SsoUserInfo
	 * @return Kv
	**/
	private Kv createBladeToken(SsoUserInfo ssoUserInfo){
		UserInfo userInfo = transferSsoUserInfo2BladeUserInfo(ssoUserInfo);
		Kv kv = TokenUtil.createAuthInfo(userInfo);
		log.info("生成blade-token: " + kv.get("access_token"));
		// 临时解决方案， 生成token后延迟200ms 返回前端
		try {
			Thread.sleep(200L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return kv;
	}
	private UserInfo transferSsoUserInfo2BladeUserInfo(SsoUserInfo ssoUserInfo){
		UserInfo userInfo = new UserInfo();
		BeanUtils.copyProperties(ssoUserInfo, userInfo);
		User user = new User();
		BeanUtils.copyProperties(ssoUserInfo.getUser(), user);
		userInfo.setUser(user);
		userInfo.setDetail(transferDetail(ssoUserInfo.getDetail()));
		return userInfo;
	}
	private Kv transferDetail(Map<String, Object> map){
		Kv kv = Kv.create();
		for (Map.Entry<String, Object> entry:map.entrySet()) {
			kv.set(entry.getKey(), entry.getValue());
		}
		return kv;
	}

	/**
	 * ##目前弃用##
	 * description: 用户退出，清除缓存 <br>
	 * author: yzpang <br>
	 * param:
	 * @return
	 **/
	@Deprecated
	@GetMapping("/oauth/logOut")
	public Kv logOut(){
		// 清除缓存
		BladeUser user = AuthUtil.getUser();
		log.info("退出登录用户:" + user);
		if (user != null && jwtProperties.getState()) {
			String token = JwtUtil.getToken(WebUtil.getRequest().getHeader(TokenConstant.HEADER));
			JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token);
		}

		Kv kv = Kv.create();
		//kv.put("apiUrl", bladeSsoProperties.getLogoutUrl());
		return kv;

		//return "redirect:" + bladeSsoProperties.getLogoutUrl();
	}



}
